/******************************************************************************
 * Copyright (C) 671643387@qq.com
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 *****************************************************************************/

#ifndef GAME_GAME_OBJECT_H_
#define GAME_GAME_OBJECT_H_

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif

#include <cstddef>
#include <cstdint>
#include <cassert>
#include <NodeCpp/Macros.h>
#include "ObjectDefines.h"
#include "ObjectGuid.h"

class Object
{
public:
    Object(void);
    virtual ~Object(void);

    std::uint8_t GetTypeId(void) const { return ObjectTypeId_; }

    void SetUInt32Value(std::uint16_t _Index, std::uint32_t _Value);
    void SetUInt64Value(std::uint16_t _Index, const std::uint64_t& _Value);
    void SetGuidValue(std::uint16_t _Index, ObjectGuid const& _Value) { SetUInt64Value(_Index, _Value.GetRawValue()); }
	const std::uint64_t& GetUInt64Value(std::uint16_t _Index) const;
	const ObjectGuid& GetGuidValue(std::uint16_t _Index) const { return *reinterpret_cast<ObjectGuid const*>(&GetUInt64Value(_Index)); }

	const ObjectGuid& GetObjectGuid(void) const { return GetGuidValue(OBJECT_FIELD_GUID); }
	const std::uint64_t& GetGUID(void) const { return GetUInt64Value(OBJECT_FIELD_GUID); }
	std::uint32_t GetGUIDLow(void) const { return GetObjectGuid().GetCounter(); }

protected:
    virtual void AddToClientUpdateList(void);
    bool Object::PrintIndexError(std::uint32_t _Index, bool _Set) const;

private:
    void Object::_InitValues(void);
    void _Create(std::uint32_t _Guidlow, std::uint32_t _Entry, HighGuid _Guidhigh);
    void _MarkForClientUpdate(void);

    std::uint16_t ObjectType_;
    std::uint8_t ObjectTypeId_;
    union {
        std::uint32_t* UInt32Values_;
    };
    std::vector<bool> ChangedValues_;
    std::size_t ValuesCount_;
    bool ObjectUpdated_;
    bool InWorld_;

    PackedGuid PackGUID_;
    DISALLOW_COPY_AND_ASSIGN(Object);
};

#endif // GAME_GAME_OBJECT_H_
